package com.hk.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hk.exception.ErrorCode;
import com.hk.exception.ThrowExceptionUtil;
import com.hk.model.entity.Picture;
import com.hk.model.entity.Space;
import com.hk.model.vo.analyze.*;
import com.hk.model.vo.user.UserVO;
import com.hk.service.PictureService;
import com.hk.service.SpaceAnalyzeService;
import com.hk.service.SpaceService;
import com.hk.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author huangkun
 * @date 2025/1/18 11:11
 */
@Service
@Slf4j
public class SpaceAnalyzeServiceImpl implements SpaceAnalyzeService {
    @Resource
    private UserService userService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private SpaceService spaceService;

    @Resource
    private PictureService pictureService;

    @Override
    public SpaceAnalyzeResponseVO spaceAnalyze(SpaceAnalyzeRequestVO analyzeRequestVO) {
        //校验权限
        String spaceId = analyzeRequestVO.getSpaceId();
        Boolean isPublic = analyzeRequestVO.getIsPublic();
        Boolean isAll = analyzeRequestVO.getIsAll();
        checkPermission(isAll, isPublic, spaceId);

        Space space = spaceService.getById(spaceId);
        //查询图片
        LambdaQueryWrapper<Picture> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(spaceId)) {
            queryWrapper.eq(StrUtil.isNotBlank(spaceId), Picture::getSpaceId, spaceId);
        } else if (isPublic) {
            queryWrapper.isNull(Picture::getSpaceId);
        }
        queryWrapper.select(Picture::getPicSize);
        List<Object> objects = pictureService.getBaseMapper().selectObjs(queryWrapper);
        long useSize = 0L;
        long imageCount = (long) objects.size();
        if (CollectionUtil.isNotEmpty(objects)) {
            useSize = objects.stream().mapToLong(obj -> (Long) obj).sum();
        }
        SpaceAnalyzeResponseVO responseVO = new SpaceAnalyzeResponseVO();
        responseVO.setUsedSize(useSize);
        responseVO.setCurrentImageCount(imageCount);
        if (StrUtil.isNotBlank(spaceId)) {
            Long maxSize = space.getMaxSize();
            double usedPercent = NumberUtil.round(useSize * 100D /maxSize , 2).doubleValue();
            responseVO.setTotalSize(maxSize);
            responseVO.setUsedPercent(usedPercent);
            Long maxCount = space.getMaxCount();
            double imagePercent = NumberUtil.round(imageCount * 100D / maxCount, 2).doubleValue();
            responseVO.setMaxImageCount(maxCount);
            responseVO.setImagePercent(imagePercent);
        }
        return responseVO;
    }

    @Override
    public List<CategoryAnalyzeResponseVO> categoryAnalyze(SpaceAnalyzeRequestVO analyzeRequestVO) {
        //校验权限
        String spaceId = analyzeRequestVO.getSpaceId();
        Boolean isPublic = analyzeRequestVO.getIsPublic();
        Boolean isAll = analyzeRequestVO.getIsAll();
        checkPermission(isAll, isPublic, spaceId);


        LambdaQueryWrapper<Picture> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(spaceId)) {
            queryWrapper.eq(StrUtil.isNotBlank(spaceId), Picture::getSpaceId, spaceId);
        } else if (isPublic) {
            queryWrapper.isNull(Picture::getSpaceId);
        }
        queryWrapper.select(Picture::getPicSize, Picture::getCategory);
        List<Map<String, Object>> maps = pictureService.getBaseMapper().selectMaps(queryWrapper);
        List<CategoryAnalyzeResponseVO> list = null;
        if (CollectionUtil.isNotEmpty(maps)) {
            //封装响应对象
            list = maps.stream().collect(Collectors.groupingBy(map -> (String) map.getOrDefault("category", "默认"), Collectors.summingLong(map -> (Long) map.get("picSize")))).entrySet().stream().map(entry -> {
                CategoryAnalyzeResponseVO responseVO = new CategoryAnalyzeResponseVO();
                responseVO.setCategoryName(entry.getKey());
                responseVO.setUsedSize(entry.getValue());
                responseVO.setCurrentImageCount(maps.stream().filter(map -> entry.getKey().equals(map.getOrDefault("category", "默认"))).count());
                return responseVO;
            }).sorted(Comparator.comparingLong(CategoryAnalyzeResponseVO::getUsedSize).reversed()).collect(Collectors.toList());
        }
        return list;
    }

    @Override
    public List<TagAnalyzeResponseVO> tagAnalyze(SpaceAnalyzeRequestVO analyzeRequestVO) {
        //校验权限
        String spaceId = analyzeRequestVO.getSpaceId();
        Boolean isPublic = analyzeRequestVO.getIsPublic();
        Boolean isAll = analyzeRequestVO.getIsAll();
        checkPermission(isAll, isPublic, spaceId);

        LambdaQueryWrapper<Picture> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(spaceId)) {
            queryWrapper.eq(StrUtil.isNotBlank(spaceId), Picture::getSpaceId, spaceId);
        } else if (isPublic) {
            queryWrapper.isNull(Picture::getSpaceId);
        }
        queryWrapper.select(Picture::getPicSize, Picture::getTags);
        List<Map<String, Object>> maps = pictureService.getBaseMapper().selectMaps(queryWrapper);
        List<TagAnalyzeResponseVO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(maps)) {
            //带有标签的图片
            List<TagAnalyzeResponseVO> havaTagList = maps.stream().filter(map -> StrUtil.isNotBlank((String) map.get("tags"))).flatMap(map -> {
                String tags = (String) map.get("tags");
                Long picSize = (Long) map.get("picSize");
                List<String> tagList = JSONUtil.toList(tags, String.class);
                return tagList.stream().map(tag -> new AbstractMap.SimpleEntry<>(tag, picSize));
            }).collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.collectingAndThen(Collectors.toList(), entries -> {
                long totalSize = entries.stream().mapToLong(Map.Entry::getValue).sum();
                long count = entries.size();
                return new TagAnalyzeResponseVO(entries.get(0).getKey(), totalSize, count);
            }))).values().stream().toList();
            list.addAll(havaTagList);


            //没有标签的图片
            List<Map<String, Object>> notTagList = maps.stream().filter(map -> StrUtil.isBlank((String) map.get("tags"))).toList();
            if (CollectionUtil.isNotEmpty(notTagList)) {
                long size = notTagList.stream().mapToLong(map -> (Long) map.get("picSize")).sum();
                long count = notTagList.stream().mapToLong(map -> (Long) map.get("picSize")).count();
                TagAnalyzeResponseVO responseVO = new TagAnalyzeResponseVO("无标签", size, count);
                list.add(responseVO);
            }
        }

        list.sort(Comparator.comparingLong(TagAnalyzeResponseVO::getCurrentImageCount).reversed());

        return list;
    }


    @Override
    public List<PictureSizeAnalyzeResponseVO> pictureSizeAnalyze(SpaceAnalyzeRequestVO analyzeRequestVO) {
        String spaceId = analyzeRequestVO.getSpaceId();
        Boolean isPublic = analyzeRequestVO.getIsPublic();
        Boolean isAll = analyzeRequestVO.getIsAll();
        checkPermission(isAll, isPublic, spaceId);

        LambdaQueryWrapper<Picture> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(spaceId)) {
            queryWrapper.eq(StrUtil.isNotBlank(spaceId), Picture::getSpaceId, spaceId);
        } else if (isPublic) {
            queryWrapper.isNull(Picture::getSpaceId);
        }
        queryWrapper.select(Picture::getPicSize);
        List<Object> objectList = pictureService.getBaseMapper().selectObjs(queryWrapper);
        List<PictureSizeAnalyzeResponseVO> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(objectList)) {
            //将数据划分为 0m-1m 1m-2m 2m以上的三个区间  小于
            result = objectList.stream().map(o -> Long.valueOf(o.toString())).collect(Collectors.groupingBy(size -> {
                if (size < 1024 * 1024) {
                    return "0m-1m";
                } else if (size < 2 * 1024 * 1024) {
                    return "1m-2m";
                } else {
                    return "2m以上";
                }
            })).entrySet().stream().map(entry -> new PictureSizeAnalyzeResponseVO(entry.getKey(), (long) entry.getValue().size())).toList();
        }
        return result;
    }

    private void checkPermission(Boolean isAll, Boolean isPublic, String spaceId) {
        boolean isAdmin = userService.isAdmin(request);
        if (isAll || isPublic) {
            //校验权限，只有管理员有权限
            ThrowExceptionUtil.throwIf(!isAdmin, ErrorCode.NO_PERMISSION);
        } else {
            Space space = spaceService.getById(spaceId);
            ThrowExceptionUtil.throwIf(space == null, ErrorCode.ERROR_PARAM, "空间不存在");
            UserVO userVO = userService.getCurrentUser(request);
            ThrowExceptionUtil.throwIf(ObjUtil.notEqual(space.getUserId(), userVO.getId()) && !isAdmin, ErrorCode.NO_PERMISSION);
        }
    }
}
